package com.reflect.demo06;

import com.reflect.demo05.User;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

// 通过反射，动态的创建对象
public class Test {
    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException {
        // 获得 Class 对象
        Class cls = Class.forName("com.reflect.demo05.User");
        /**
         * 通过Class 对象来创建对象
         */
        // 方式一：通过 newInstance()方法
        //User user = (User)cls.newInstance(); // 本质是调用了类的无参构造器，如果没有 就会报错
        //System.out.println(user); // User{name='null', age=0}

        // 方式二：通过构造方法 getDeclaredConstructor 构建对象
        //Constructor constructor = cls.getDeclaredConstructor(String.class,int.class);
        //User user2 = (User) constructor.newInstance("哇哈哈", 100); // 设置参数
        //System.out.println(user2);// User{name='哇哈哈', age=100}

        /**
         * 通过反射来调用方法
         * 1.通过反射 创建对象
         * 2.通过反射获取一个方法
         * 3.调用方法
         */
        User user = (User)cls.newInstance();
        // 可以直接调用方法
        System.out.println(user.toString());
        System.out.println(user.go());
        System.out.println(user.getAge());
        // 获取方法 getMethod()
        //Method setName = cls.getMethod("setName", String.class);
        Method setName = cls.getDeclaredMethod("setName", String.class);
        //invoke(对象，方法的参数):激活一个方法 属于 Method 类方法
        Object o = setName.invoke(user,"kerry study java every day");
        System.out.println("====");
        System.out.println(o); // null
        // 获取name值 调用 getName 方法
        Method getName = cls.getDeclaredMethod("getName",null);
        System.out.println(getName.invoke(user, null));
        System.out.println("======");
        //System.out.println(user.getName());
        user.setAge(100);
        System.out.println(user.getAge());

        // 通过反射来操作属性
        System.out.println("========操作属性========");
        User user4 = (User) cls.newInstance();
        // 获取属性
        Field name = cls.getDeclaredField("name");
        System.out.println(name); // private java.lang.String com.reflect.demo05.User.name
        // Field的set 方法 set(对象，参数的值)
        /**
         * 调用 name.set（）方法报错
         * IllegalAccessException 报错，是因为方法的访问权限是private导致，
         * 需要关闭权限验证 使用 field.setAccessible(true) 关闭
         */
        name.setAccessible(true);
        name.set(user4,"xdm们，我交大了");
        System.out.println(name.getName()); // name
        System.out.println(user4.getName()); // xdm们，我交大了
    }
}
